#include "AbrahamLincoln.h"
#include "include.h"
#define TEXTURE_FILE "./Images/lincoln.bmp"
#define POSE_FILE "./Images/lincolnpose.bmp"
#define SKELETON_FILE "./Skeletons/testSkeleton.skl"
//"./Skeletons/dinoSkeleton.skl"
#define BEARD_TEXTURE "./Images/beard.bmp"

#define TIGHT_BEARD 1500.0
#define LOOSE_BEARD 1500.0
AbrahamLincoln::~AbrahamLincoln()
{
	printf("Deleting Abe\n");
	if(beardString)
		delete(beardString);
	beardString = NULL;
	printf("Deleting Abe4\n");
	
}
AbrahamLincoln::AbrahamLincoln( SupplyBag * supplyBag,
			TextureManager * textureManager,
			Vector2D position, 
			float mass) 
: ControlledVertibrateObject(textureManager, position, NULL, 0,  mass, true, SKELETON_FILE)
{
	this->supplyBag = supplyBag;
	objectId = PLAYER_OBJECT_CLASS;
	numVertices = 4;
	vertices = (Vector2D *)malloc(sizeof(Vector2D)*4);
	vertices[0] = Vector2D(-1.5,6);
	vertices[1] = Vector2D(1.5,6);
	vertices[2] = Vector2D(1.5,-6);
	vertices[3] = Vector2D(-1.5,-6);
	if(textureManager)
	{
		if(!textureManager->LoadTexture(DUST_FILE))
		{
			printf("Failed to load %s\n", DUST_FILE);
		}
	}

	beardAnchorOffset = Vector2D(0.0, 5.0);
	beardAnchor = position + beardAnchorOffset;
	beardString = new Beard(&beardAnchor,5, 0.1, 0.1, 1500.0, textureManager, BEARD_TEXTURE);
	CalculateUpVector();
	CalculateMomentOfInertia();
}
bool AbrahamLincoln::CanCollideWith(Object * object)
{
	if( beardString->grabbingObject && beardString->grabObject == object && !beardString->grabObject->collideWhenGrabbed)
		return false;
	return true;
}
void AbrahamLincoln::ControlledVertibrateObjectThinkEntryPoint(double elapsedTime)
{
	Vector2D axis = vertices[2] - vertices[3];
	axis = !axis;
	
	if((facingRight && !isOnRightWall) || isOnLeftWall)
	{
		beardAnchor = position + beardAnchorOffset + axis * 0.6;
	}
	else
	{
		beardAnchor = position + beardAnchorOffset - axis * 0.6;
	}
}
void AbrahamLincoln::ControlledObjectThinkEntryPoint(double elapsedTime)
{
	Vector2D force = beardString->Think(elapsedTime);
	
	float beardLength = beardString->GetLength();
	if(beardLength > 100 && beardString->grabbingObject)
	{
		beardString->Release();
		//beardString->SetSpringConstant(TIGHT_BEARD);
	}
	else if(beardLength > 30 && beardString->grabbingObject)
		AddForce(0.2 * force);
	//, *beardString->anchor);
}
void AbrahamLincoln::ControlledObjectDrawEntryPoint()
{
	beardString->Draw();
}
void AbrahamLincoln::ControlledObjectRotateEntryPoint(float cosTheta, float sinTheta)
{
	float newX = beardAnchorOffset.x * cosTheta - beardAnchorOffset.y * sinTheta;
	float newY = beardAnchorOffset.y * cosTheta + beardAnchorOffset.x * sinTheta;
	beardAnchorOffset.x = newX;
	beardAnchorOffset.y = newY;
	beardAnchor = position + beardAnchorOffset;
}
void AbrahamLincoln::ControlledObjectAddGravityEntryPoint()
{
	beardString->AddGravitationalForce();
}
void AbrahamLincoln::ControlBeard(bool left, bool right, bool up, bool down)
{
	beardString->Whip(left, right, up, down);
}
void AbrahamLincoln::ControlBeard(Vector2D mousePoint)
{
	beardString->Whip(mousePoint);	
}
void AbrahamLincoln::MoveBeard(Vector2D mousePoint)
{
	if(isOnGround)
		beardString->Move(mousePoint);	
}
void AbrahamLincoln::BeardRelease()
{
	beardString->Release();
	//beardString->SetSpringConstant(TIGHT_BEARD);
}
bool AbrahamLincoln::BeardCollide(ObjectList * objectList)
{
	//return false;
	//if(beardString->pauseUntilShrink)
	//	return false;
	Object ** object = NULL;
	object = new Object*;
	Vector2D * location = new Vector2D(0,0);
	if(beardString->Collide(objectList, this, object, location))
	{
		if(*object == NULL)
		{
			printf("Object is null\n");
			delete object;
			return false;
		}
		if(*object == this)
		{
			printf("Object is null me\n");
			delete object;
			return false;
		}

		/*Vector2D towardMe = (*object)->position - position;

		towardMe = !towardMe * 1000;
		(*object)->AddForceObjectSpace(towardMe, *location);
		AddForce(-1.0*towardMe);*/
		
		//printf("location = (%f, %f)\n", location->x, location->y);
		(*object)->AddKeyPoint(location);
		//printf("keyPoint = (%f, %f)\n", keyPoint->x, keyPoint->y);
		beardString->Grab(*object, location);
		//beardString->SetSpringConstant(LOOSE_BEARD);
		//beardString->SetDampingConstant((*object)->mass);
		//delete object;
		return true;	
	}
	delete object;
	return false;
}
GrenadeObject * AbrahamLincoln::UseGrenade()
{
	if(supplyBag->RemoveGrenade())
	{
			Vector2D grenadePosition = position + !velocity * 5.0;
			GrenadeObject * grenade = new GrenadeObject(textureManager,grenadePosition, Vector2D(0.0, 0.0), Vector2D(0.0, 0.0), 
						 		0.0, 0.0, 0.0, 1.0, 3.0, 60000, false);
	
			Vector2D * location = new Vector2D(0,0);
			grenade->AddKeyPoint(location);
		//printf("keyPoint = (%f, %f)\n", keyPoint->x, keyPoint->y);
			beardString->Grab(grenade, location);
			return grenade;
	}	
	return NULL;
}
